package com.mmg.cosplay.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mmg.cosplay.entity.dto.RoleRankingDTO;
import com.mmg.cosplay.entity.po.RolePreset;
import com.mmg.cosplay.service.IRolePresetService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
@RequiredArgsConstructor
@Service
public class RankingListService {

    private final StringRedisTemplate redisTemplate;
    private final IRolePresetService rolePresetService;

    // Redis key前缀
    private static final String RANKING_KEY_PREFIX = "ranking:daily:";
    
    /**
     * 获取今日排行榜Redis key
     */
    private String getTodayRankingKey() {
        String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return RANKING_KEY_PREFIX + today;
    }

    /**
     * 增加角色今日使用次数
     * @param roleId 角色ID
     */
    public void incrementRoleUsage(Long roleId) {
        try {
            String key = getTodayRankingKey();
            redisTemplate.opsForZSet().incrementScore(key, roleId.toString(), 1);
            log.info("角色ID: {} 今日使用次数已增加", roleId);
        } catch (Exception e) {
            log.error("增加角色今日使用次数失败，角色ID: {}", roleId, e);
        }
    }

    /**
     * 获取今日排行榜
     * @param limit 返回数量限制
     * @return 排行榜列表
     */
    public List<RoleRankingDTO> getTodayRanking(int limit) {
        try {
            String key = getTodayRankingKey();
            // 获取分数最高的前limit个角色（降序）
            Set<ZSetOperations.TypedTuple<String>> rankingSet = 
                redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, limit - 1);
            
            List<RoleRankingDTO> rankingList = new ArrayList<>();
            int rank = 1;
            
            for (ZSetOperations.TypedTuple<String> tuple : rankingSet) {
                String roleIdStr = tuple.getValue();
                Double score = tuple.getScore();
                
                if (roleIdStr != null && score != null) {
                    Long roleId = Long.valueOf(roleIdStr);
                    RolePreset rolePreset = rolePresetService.getById(roleId);
                    
                    if (rolePreset != null) {
                        RoleRankingDTO dto = new RoleRankingDTO();
                        dto.setRank(rank++);
                        dto.setRoleId(roleId);
                        dto.setRoleName(rolePreset.getRoleName());
                        dto.setRoleDescription(rolePreset.getRoleDescription());
                        dto.setAvatarUrl(rolePreset.getAvatarUrl());
                        dto.setTodayUsageCount(score.longValue());
                        dto.setTotalUsageCount(rolePreset.getUsageCount());
                        rankingList.add(dto);
                    }
                }
            }
            
            return rankingList;
        } catch (Exception e) {
            log.error("获取今日排行榜失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 清空今日排行榜数据并预热默认数据
     */
    public void clearTodayRanking() {
        try {
            String key = getTodayRankingKey();
            // 清空当前排行榜数据
            redisTemplate.delete(key);
            log.info("今日排行榜数据已清空");
            
            // 预热默认数据
            preloadDefaultRanking();
            
        } catch (Exception e) {
            log.error("清空今日排行榜数据失败", e);
        }
    }

    /**
     * 预热默认排行榜数据
     * 获取按创建时间倒序的前10条公开角色数据
     */
    public void preloadDefaultRanking() {
        try {
            // 查询按创建时间倒序的前10条公开角色
            LambdaQueryWrapper<RolePreset> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RolePreset::getIsPrivate, 1) // 1表示公开
                       .orderByDesc(RolePreset::getCreateTime)
                       .last("LIMIT 10");
            
            List<RolePreset> defaultRoles = rolePresetService.list(queryWrapper);
            
            if (!defaultRoles.isEmpty()) {
                String key = getTodayRankingKey();
                
                // 将默认角色添加到Redis中，初始分数为0
                for (RolePreset role : defaultRoles) {
                    redisTemplate.opsForZSet().add(key, role.getId().toString(), 0);
                }
                
                log.info("已预热 {} 条默认排行榜数据", defaultRoles.size());
            } else {
                log.warn("没有找到可用的公开角色进行预热");
            }
            
        } catch (Exception e) {
            log.error("预热默认排行榜数据失败", e);
        }
    }

    /**
     * 手动预热排行榜数据（可用于初始化或测试）
     */
    public void manualPreloadRanking() {
        log.info("开始手动预热排行榜数据");
        preloadDefaultRanking();
    }

    /**
     * 获取角色今日使用次数
     * @param roleId 角色ID
     * @return 今日使用次数
     */
    public Long getRoleTodayUsage(Long roleId) {
        try {
            String key = getTodayRankingKey();
            Double score = redisTemplate.opsForZSet().score(key, roleId.toString());
            return score != null ? score.longValue() : 0L;
        } catch (Exception e) {
            log.error("获取角色今日使用次数失败，角色ID: {}", roleId, e);
            return 0L;
        }
    }
}
